#include <time.h>

#ifdef UNIX
# include <sys/time.h>
#else
# include <windows.h>
#endif

#include "../hle.h"

void sceKernelDcacheInvalidateRange()
{
    _log(INF, HLE, "sceKernelDcacheInvalidateRange(ptr = %08x, size = %08x)", PARAM(0), PARAM(1));
}

void sceKernelIcacheInvalidateRange()
{
    _log(INF, HLE, "sceKernelIcacheInvalidateRange(ptr = %08x, size = %08x)", PARAM(0), PARAM(1));
}

void sceKernelGetGPI()
{
    _log(TRC, HLE, "0 = sceKernelGetGPI()");
    RETURN(0);
}

void sceKernelSetGPO()
{
    _log(TRC, HLE, "sceKernelSetGPO(%02x)", PARAM(0));
    RETURN(0);
}

void sceKernelLibcClock()
{
    clock_t retVal = clock();
    _log(INF, HLE, "%d = sceKernelLibcClock", retVal);
    RETURN(retVal);
}

void sceKernelLibcTime()
{
    u32 retVal;
    time_t timeval;

    if (mem_isOk(PARAM(0))) {
        retVal = time(&timeval);
        mem_writeStruct(PARAM(0), &timeval, sizeof(time_t));
    }
    else
        retVal = time(NULL);

    _log(WRN, HLE, "%d = sceKernelLibcTime()", retVal);
    RETURN(retVal);
}

void sceKernelLibcGettimeofday()
{
#ifndef UNIX
    struct timezone {
        s32 tz_minuteswest;
        s32 tz_dsttime;
    };

    FILETIME ft;
    u64 tmpres = 0;
    static s32 tzflag;
#endif

    struct timeval tv;
    struct timezone tz;

    _log(INF, HLE, "sceKernelLibcGettimeofday()");

#ifdef UNIX
    gettimeofday(&tv, &tz);
#else
    GetSystemTimeAsFileTime(&ft);
 
    tmpres |= ft.dwHighDateTime;
    tmpres <<= 32;
    tmpres |= ft.dwLowDateTime;

    tmpres -= 11644473600000000ULL; /* delta epoch in microseconds */
    tmpres /= 10;
    tv.tv_sec = (u32)(tmpres / 1000000UL);
    tv.tv_usec = (u32)(tmpres % 1000000UL);
 
    if (!tzflag) {
        _tzset();
        tzflag++;
    }

    tz.tz_minuteswest = _timezone / 60;
    tz.tz_dsttime = _daylight;
#endif

    if (mem_isOk(PARAM(0)))
        mem_writeStruct(PARAM(0), &tv, sizeof(struct timeval));
    if (mem_isOk(PARAM(1)))
        mem_writeStruct(PARAM(1), &tz, sizeof(struct timezone));

    RETURN(0);
}

void sceKernelDcacheWritebackAll()
{
    _log(INF, HLE, "sceKernelDcacheWritebackAll()");
}

void sceKernelDcacheWritebackInvalidateAll()
{
    _log(INF, HLE, "sceKernelDcacheWritebackInvalidateAll()");
}

void sceKernelDcacheWritebackRange()
{
    _log(INF, HLE, "sceKernelDcacheWritebackRange(ptr = %08x, size = %08x)", PARAM(0), PARAM(1));
}

void sceKernelDcacheWritebackInvalidateRange()
{
    _log(INF, HLE, "sceKernelDcacheWritebackInvalidateRange(ptr = %08x, size = %08x)", PARAM(0), PARAM(1));
}

void sceKernelIcacheInvalidateAll()
{
    _log(INF, HLE, "sceKernelIcacheInvalidateAll()");
}

